#ifndef IGSLIB_COMMON_USE_H
#define IGSLIB_COMMON_USE_H

#include <set>
#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <exception>
#include "igslib_typedef.h"
#include "igslib_iutil.h"
#include <android/log.h>

#define slient_delete(a0) \
    if (a0 != nullptr) \
    { \
        delete a0;\
        a0 = nullptr; \
    }

namespace igslib
{
    /*!
     * New component should always inherits this interface to
     * ensure that the destructor of derived component can be invoked.
     */
    struct IComponent
    {
        virtual ~IComponent() {}
    };

    /*!
     * This class will destruct its children when destructing itself.
     * But the most important thing is, author of new components MUST
     * insert them to `cpns` while `new` any components.
     */
    template <typename ct> class IManager
    {
        protected:
            std::set<ct> cpns;
        public:
            virtual ~IManager()
            {
                for(auto each:cpns)
                {
                    slient_delete(each);
                    each = nullptr;
                }
            }
    };
};

/*!
 * NRE: No Runtime Exception.
 * If we REALLY don't want any exception at runtime, we can add `#define NRE` at source or at Makefile.
 * This is NOT recommended, because all problems will ignored and may cuase app crash at anyother place, please note.
 */
#ifdef NRE
    #define throw_igslib_exception(a)
#else
    #define throw_igslib_exception(a) igslib::exception_with_filename_linenum(a,__FILE__,__LINE__)
#endif
namespace igslib
{
    static void exception_with_filename_linenum(const std::string& msg,const char* file_name,int line_number)
    {
        std::stringstream tmp;
		tmp << "\n==================";
		tmp << "\n[igslib_exception]";
		tmp << "\n==================\n";
		tmp << file_name << ":" << line_number << std::endl << msg;
        __android_log_print(ANDROID_LOG_DEBUG, "<igslib exception>: ",  "%s", tmp.str().c_str());
        printf("<igslib exception>: %s",tmp.str().c_str());
        throw std::runtime_error(tmp.str());
    }
};
#endif
